package me.ingxin.android.permission2.ext

import android.content.Context
import androidx.activity.result.contract.ActivityResultContract
import me.ingxin.android.permission2.request.Request
import me.ingxin.android.permission2.request.Task
import me.ingxin.android.permission2.request.TaskChain
import me.ingxin.android.permission2.specialPermissionGranted
import me.ingxin.android.permission2.view.GuideView

/**
 * Created on 2023/7/13 by yin
 * 需要跳转到单独的设置页面打开权限
 */
internal abstract class SpecialPermissionsTask<I, O> : Task {

    private var reasonView: GuideView? = null

    abstract val permission: String
    abstract val contract: ActivityResultContract<I, O>

    override fun runTask(chain: TaskChain, request: Request) {
        reasonView?.applyDismiss()
        if (request.specialPermissions.contains(permission) && showRequestPermission(chain.context)) {
            if (chain.context.specialPermissionGranted(permission)) {
                chain.proceed(request)
            } else {
                doRequestAndShowDialog(chain, request)
            }
        } else {
            //当前版本不需要申请
            chain.proceed(request)
        }
    }

    /**
     * 是否可以申请该权限（不考虑权限获得情况，只考虑当前版本）
     */
    abstract fun showRequestPermission(context: Context): Boolean

    /**
     * 创建启动参数
     */
    abstract fun crateInput(context: Context): I

    /**
     * 发起权限申请
     */
    protected open fun requestPermission(chain: TaskChain, request: Request) {
        val input = crateInput(chain.context)
        val fragment = RequestSpecialFragment<I, O>()
        fragment.attach(input, contract) { runSelfAgain(chain, request) }
        chain.fragmentManager.beginTransaction().add(fragment, fragment.javaClass.name)
            .commitAllowingStateLoss()
    }

    /**
     * 再一次执行自己
     */
    private fun runSelfAgain(chain: TaskChain, request: Request) {
        runTask(chain, request)
    }

    private fun showReasonView(chain: TaskChain, request: Request) {
        reasonView = request.guide.getShowReasonView(chain.context, listOf(permission), {
            it.applyDismiss()
            requestPermission(chain, request)
        }) {
            it.applyDismiss()
            chain.proceed(request)
        }
        reasonView?.applyShow()
    }

    /**
     * 开始权限申请的流程并显示理由对话框
     */
    protected open fun doRequestAndShowDialog(chain: TaskChain, request: Request) {
        showReasonView(chain, request)
    }

}